﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
using WxMpApiDemo.Models;

namespace WxMpApiDemo.Services
{
    public class JiuChunTangService: IJiuChunTangService
    {
        private readonly HttpClient _httpClient;
        private string _accessToken;
        private DateTime _tokenExpireTime = DateTime.MinValue;

        /// <summary>
        /// HttpClient 会通过工厂注入
        /// </summary>
        /// <param name="httpClient"></param>
        public JiuChunTangService(HttpClient httpClient)
        {
            _httpClient = httpClient;
        }

        /// <summary>
        /// 获取访问令牌
        /// </summary>
        /// <param name="forceRefresh">是否强制刷新令牌</param>
        /// <returns>访问令牌</returns>
        public async Task<string> GetAccessTokenAsync(bool forceRefresh = false)
        {
            try
            {
                // 如果令牌未过期且不强制刷新，则直接返回缓存的令牌
                if (!string.IsNullOrEmpty(_accessToken) && DateTime.Now < _tokenExpireTime && !forceRefresh)
                {
                    return _accessToken;
                }

                // 构建表单数据
                var formData = new FormUrlEncodedContent(new[]
                {
                    new KeyValuePair<string, string>("appid", "appLWfbIPtngXcDPmtNdwya"),
                    new KeyValuePair<string, string>("secret", "aa4e093b68ad9b308657bada143d98281ddb6d4eccfe78c51591835221784f4f"),
                    new KeyValuePair<string, string>("grant_type", "client_credentials"),
                    new KeyValuePair<string, string>("scope", "all"),
                    new KeyValuePair<string, string>("force_refresh", forceRefresh.ToString().ToLower())
                });

                // 发送请求
                var response = await _httpClient.PostAsync("token", formData);
                response.EnsureSuccessStatusCode();

                // 解析响应
                var content = await response.Content.ReadAsStringAsync();
                var tokenResponse = JsonSerializer.Deserialize<TokenResponse>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
                if (tokenResponse != null && !string.IsNullOrEmpty(tokenResponse.access_token))
                {
                    _accessToken = tokenResponse.access_token;
                    _tokenExpireTime = DateTime.Now.AddSeconds(tokenResponse.expires_in);
                    return _accessToken;
                }

                throw new Exception("获取访问令牌失败: " + content);
            }
            catch (Exception ex)
            {
                throw new Exception("获取访问令牌失败", ex);
            }
        }

        /// <summary>
        /// 获取公众号二维码
        /// </summary>
        /// <param name="sceneStr">场景值字符串</param>
        /// <param name="expireSeconds">过期时间（秒）</param>
        /// <returns>二维码信息</returns>
        public async Task<QrCodeResponse> CreateQrCodeAsync(string sceneStr, int expireSeconds = 76)
        {

            // 确保有有效的访问令牌
            var token = await GetAccessTokenAsync();

            // 构建请求体
            var requestData = new
            {
                action_name = "QR_LIMIT_SCENE",
                expire_seconds = expireSeconds,
                scene_str = sceneStr,
            };

            var jsonContent = new StringContent(JsonSerializer.Serialize(requestData), Encoding.UTF8, "application/json");


            /////////////////////
            /*

            var client = new HttpClient();
            var request = new HttpRequestMessage(HttpMethod.Post, $"https://test.jiuchuntang.cn/api/open-api/v1/wx-mp/qrcode/create?access_token={token}");            
            request.Content = jsonContent;
            var response1 = await client.SendAsync(request);
            response1.EnsureSuccessStatusCode();
            Console.WriteLine(await response1.Content.ReadAsStringAsync());

            */
            //////////////////////////////

            // 发送请求
            var response = await _httpClient.PostAsync($"wx-mp/qrcode/create?access_token={token}", jsonContent);
            response.EnsureSuccessStatusCode();

            // 解析响应
            var content = await response.Content.ReadAsStringAsync();
            var qrCodeResponse = JsonSerializer.Deserialize<QrCodeResponse>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });

            if (qrCodeResponse == null)
            {
                throw new Exception("获取二维码失败: " + content);
            }

            return qrCodeResponse;
        }

        /// <summary>
        /// 查询二维码扫码状态
        /// </summary>
        /// <param name="eventId">事件ID</param>
        /// <returns>扫码状态信息</returns>
        public async Task<ScanStatusResponse> GetScanStatusAsync(string eventId)
        {
            // 确保有有效的访问令牌
            var token = await GetAccessTokenAsync();

            // 发送请求
            var response = await _httpClient.GetAsync($"hyg/scan/status?eventId={eventId}&access_token={token}");
            response.EnsureSuccessStatusCode();

            // 解析响应
            var content = await response.Content.ReadAsStringAsync();
            var statusResponse = JsonSerializer.Deserialize<ScanStatusResponse>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
            if (statusResponse == null)
            {
                throw new Exception("查询扫码状态失败: " + content);
            }

            return statusResponse;
        }

        /// <summary>
        /// 回传报告
        /// </summary>
        /// <param name="reportData">报告数据</param>
        /// <returns>回传结果</returns>
        public async Task<ReportCallbackResponse> SendReportCallbackAsync(ReportCallbackRequest reportData)
        {
            // 确保有有效的访问令牌
            var token = await GetAccessTokenAsync();

            // 构建请求体
            var jsonContent = new StringContent(JsonSerializer.Serialize(reportData), Encoding.UTF8, "application/json");

            // 发送请求
            var response = await _httpClient.PostAsync($"hyg/report/callback?access_token={token}", jsonContent);
            response.EnsureSuccessStatusCode();

            // 解析响应
            var content = await response.Content.ReadAsStringAsync();
            var callbackResponse = JsonSerializer.Deserialize<ReportCallbackResponse>(content, new JsonSerializerOptions { PropertyNameCaseInsensitive = true });
            if (callbackResponse == null)
            {
                throw new Exception("回传报告失败: " + content);
            }

            return callbackResponse;
        }
    }
}
